<?php

/**
 * 订单明细
 *
 * @author chenping<chenping@shopex.cn>
 * @version $Id: items.php 2013-3-12 17:23Z
 */
class erpapi_shop_response_components_order_items extends erpapi_shop_response_components_order_abstract
{
    const _APP_NAME = 'ome';

    private $_obj_alias = array(
        'goods' => '商品',
        'pkg' => '捆绑商品',
        'gift' => '赠品',
        'giftpackage' => '礼包',
    );

    /**
     * 数据格式转换
     *
     * @return void
     * @author
     **/
    public function convert()
    {
        $payed=$this->_platform->_ordersdf['payed'];
        $payed = $payed ? $payed : 0.00;
        $pmt_order=$this->_platform->_ordersdf['pmt_order'];
        $pmt_order=$pmt_order ? $pmt_order : 0.00;
        $originalPrice=$payed + $pmt_order;
        $is_fail_order = false;
        $salesMLib = kernel::single('material_sales_material');
        $shop_id = $this->_platform->__channelObj->channel['shop_id'];

        foreach ($this->_platform->_ordersdf['order_objects'] as $object) {

            $quantity = $object['quantity'] ? $object['quantity'] : 1;
            $obj_amount = $object['amount'] ? $object['amount'] : bcmul($quantity, $object['price'], 3);

            $obj_sale_price = (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3)) ? $object['sale_price'] : bcsub($obj_amount, $object['pmt_price'], 3);
            $obj_type = 'goods';

            //检查货品是否存在销售物料中
            $salesMInfo = $salesMLib->getSalesMByBn($shop_id, $object['bn']);


            if (!$salesMInfo) {
                $is_fail_order = true;
            }
            $order_items = array();
            if ($salesMInfo) {
                $basicMInfos = $salesMLib->getBasicMBySalesMId($salesMInfo['sm_id']);
                if ($basicMInfos) {
                    //组织item数据

                    if ($salesMInfo['sales_material_type'] == 2) {
                        $salesMLib->calProSaleMPriceByRate($obj_sale_price, $basicMInfos);
                        $obj_type = 'pkg';
                    }
                    if ($salesMInfo['sales_material_type'] == 3) {
                        $obj_type = 'gift';
                    }

                    foreach ($basicMInfos as $k => $basicMInfo) {

                        if ($obj_type == 'pkg') {
                            $cost = $basicMInfo['cost'];
                            $price = $basicMInfo['rate_price'] ? bcdiv($basicMInfo['rate_price'], $basicMInfo['number'] * $object['quantity'], 2) : 0.00;
                            $pmt_price = 0;
                            $sale_price = $basicMInfo['rate_price'];
                            $amount = $basicMInfo['rate_price'];
                            $weight = $basicMInfo['weight'];

                            $shop_product_id = 0;
                            $divide_order_fee = 0;
                            $part_mjz_discount = 0;
                            $item_type = 'pkg';
                        } else if ($obj_type == 'gift') {
                            //如果是赠品重置相关的金额字段
                            $cost = 0.00;
                            $price = 0.00;
                            $pmt_price = 0.00;
                            $sale_price = 0.00;
                            $amount = 0.00;
                            $obj_amount = 0.00;
                            $obj_sale_price = 0.00;
                            $item_type = 'gift';
                            $shop_product_id = $object['shop_product_id'] ? $object['shop_product_id'] : 0;
                            $weight = (float)$object['weight'] ? $object['weight'] : ($basicMInfo['weight'] ? $basicMInfo['weight'] : 0.00);
                            $divide_order_fee = 0;
                            $part_mjz_discount = 0;
                        } else {

                            $cost = (float)$object['cost'] ? $object['cost'] : $basicMInfo['cost'];
                            $price = (float)$object['price'];
                            $pmt_price = (float)$object['pmt_price'];
                            $sale_price = (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3)) ? $object['sale_price'] : bcsub($obj_amount, (float)$object['pmt_price'], 3);
                            $amount = $obj_amount;
                            $weight = (float)$object['weight'] ? $object['weight'] : ($basicMInfo['weight'] ? $basicMInfo['weight'] : 0.00);
                            $shop_product_id = $object['shop_product_id'] ? $object['shop_product_id'] : 0;
                            $item_type = 'product';
                            $part_mjz_discount =0;
                            $divide_order_fee = 0;

                        }
                        $order_items[] = array(
                            'shop_goods_id' => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                            'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0,
                            'shop_product_id' => $shop_product_id,
                            'bn' => $basicMInfo['material_bn'],
                            'name' => $basicMInfo['material_name'],
                            'cost' => $cost ? $cost : 0.00,
                            'price' => $price ? $price : 0.00,
                            'pmt_price' => $pmt_price,
                            'sale_price' => $sale_price ? $sale_price : 0.00,
                            'amount' => $amount ? $amount : 0.00,
                            'weight' => $weight ? $weight : 0.00,
                            'quantity' => $basicMInfo['number'] * $object['quantity'],
                            'addon' => '',
                            'item_type' => $item_type,
                            'delete' => ($object['status'] == 'close') ? 'true' : 'false',
                            'divide_order_fee' => 0,
                            'part_mjz_discount' => 0,

                        );
                    }
                }else{
                    $is_fail_order = true;
                }

            }

            $this->_platform->_newOrder['order_objects'][] = array(
                'obj_type' => $obj_type ? $obj_type : 'goods',
                'obj_alias' => $object['obj_alias'] ? $object['obj_alias'] : $this->_obj_alias[$obj_type],
                'shop_goods_id' => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                'goods_id' => $salesMInfo['sm_id'] ? $salesMInfo['sm_id'] : 0,
                'bn' => $object['bn'] ? $object['bn'] : null,
                'name' => $object['name'],
                'price' => $object['price'] ? (float)$object['price'] : bcdiv($obj_amount, $object['quantity'], 3),
                'amount' => $obj_amount,
                'quantity' => $object['quantity'],
                'weight' => (float)$object['weight'],
                'score' => (float)$object['score'],
                'pmt_price' => (float)$object['pmt_price'],
                'sale_price' => $obj_sale_price,
                'order_items' => $order_items,
                'is_oversold' => ($object['is_oversold'] == true) ? 1 : 0,
                'oid' => $object['oid'],
                //flag可能从item上移到obj层上要保留的数据
                'delete' => ($object['status'] == 'close') ? 'true' : 'false',
                'original_str' => $object['original_str'],
                'product_attr' => $object['product_attr'],
                'promotion_id' => $object['promotion_id'],
                'divide_order_fee' => 0,
                'part_mjz_discount' => 0,
            );
            unset($order_items);
        }

        if ($is_fail_order) {
            $this->_platform->_newOrder['is_fail'] = 'true';
            $this->_platform->_newOrder['edit_status'] = 'true';
            $this->_platform->_newOrder['archive'] = '1';
        }
    }


    /**
     * 更新订单明细
     *
     * @return void
     * @author
     **/
    public function update()
    {
        // 后期修改
        if ($this->_platform->_tgOrder['ship_status'] == '0') {
            // 原单处理
            $tgOrder_object = array();
            foreach ((array)$this->_platform->_tgOrder['order_objects'] as $object) {
                $objkey = $this->_get_obj_key($object);

                $tgOrder_object[$objkey] = $object;

                $order_items = array();
                foreach ((array)$object['order_items'] as $item) {
                    $itemkey = $this->_get_item_key($item);

                    $order_items[$itemkey] = $item;
                }
                $tgOrder_object[$objkey]['order_items'] = $order_items;
            }

            $ordersdf = $this->_platform->_ordersdf;
            $payed=$this->_platform->_ordersdf['payed'];
            $payed = $payed ? $payed : 0.00;
            $pmt_order=$this->_platform->_ordersdf['pmt_order'];
            $pmt_order=$pmt_order ? $pmt_order : 0.00;
            $originalPrice=$payed + $pmt_order;
            //组织天下掉下来的新数据
            $sky_ordersdf_is_fail_order = false;
            $salesMLib = kernel::single('material_sales_material');
            $basicMStockLib = kernel::single('material_basic_material_stock');
            $basicMStockFreezeLib = kernel::single('material_basic_material_stock_freeze');

            // 接收的参数
            $ordersdf_object = array();
            foreach ((array)$ordersdf['order_objects'] as $object) {

                //obj基础数据格式化
                $quantity = $object['quantity'] ? $object['quantity'] : 1;
                $obj_amount = $object['amount'] ? $object['amount'] : bcmul($quantity, $object['price'], 3);
                $obj_sale_price = (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3)) ? $object['sale_price'] : bcsub($obj_amount, $object['pmt_price'], 3);
                $obj_type = $object['obj_type'] ? $object['obj_type'] : 'goods';

                $goods = array();
                $order_items = array();

                $salesMInfo = $salesMLib->getSalesMByBn($this->_platform->__channelObj->channel['shop_id'], $object['bn']);
                if (!$salesMInfo) {
                    $sky_ordersdf_is_fail_order = true;
                }
                if ($salesMInfo) {
                    $basicMInfos = $salesMLib->getBasicMBySalesMId($salesMInfo['sm_id']);
                    if (!$basicMInfos) {
                        $sky_ordersdf_is_fail_order = true;
                    }
                    if ($basicMInfos) {
                        $obj_type = 'goods';
                        if ($salesMInfo['sales_material_type'] == 2) {
                            $salesMLib->calProSaleMPriceByRate($obj_sale_price, $basicMInfos);
                            $obj_type = 'pkg';
                        }

                        if ($salesMInfo['sales_material_type'] == 3) {
                            $obj_type = 'gift';
                        }

                        //组织item数据
                        foreach ($basicMInfos as $k => $basicMInfo) {

                            $cost = (float)$object['cost'] ? $object['cost'] : $basicMInfo['cost'];
                            $price = (float)$object['price'];
                            $pmt_price = (float)$object['pmt_price'];
                            $sale_price = (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3)) ? $object['sale_price'] : bcsub($obj_amount, (float)$object_pmt, 3);
                            $amount = $obj_amount;
                            $weight = (float)$object['weight'] ? $object['weight'] : ($basicMInfo['weight'] ? $basicMInfo['weight'] : 0.00);
                            $quantity = $basicMInfo['number'] * $quantity;
                            $shop_product_id = $object['shop_product_id'];
                            $part_mjz_discount = 0;
                            $divide_order_fee = 0;
                            $item_type = 'product';
                            if ($obj_type == 'pkg') {
                                $cost = $basicMInfo['cost'];
                                $price = $basicMInfo['rate_price'] ? bcdiv($basicMInfo['rate_price'], $quantity, 2) : 0.00;
                                $pmt_price = 0;
                                $sale_price = $basicMInfo['rate_price'];
                                $amount = $basicMInfo['rate_price'];
                                $weight = $basicMInfo['weight'];
                                $divide_order_fee = 0;
                                $part_mjz_discount = 0;
                                $shop_product_id = 0;

                                $item_type = 'pkg';
                            } else if ($obj_type == 'gift') {
                                //如果是赠品重置相关的金额字段
                                $cost = 0.00;
                                $price = 0.00;
                                $pmt_price = 0.00;
                                $sale_price = 0.00;
                                $amount = 0.00;
                                $obj_amount = 0.00;
                                $obj_sale_price = 0.00;
                                $item_type = 'gift';
                                $divide_order_fee = 0;
                                $part_mjz_discount = 0;
                            }
                            $itemtmp = array(
                                'shop_goods_id' => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                                'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0,
                                'shop_product_id' => $shop_product_id,
                                'bn' => $basicMInfo['material_bn'],
                                'name' => $basicMInfo['material_name'],
                                'cost' => $cost,
                                'price' => $price,
                                'pmt_price' => $pmt_price,
                                'sale_price' => $sale_price,
                                'amount' => $amount,
                                'weight' => $weight,
                                'quantity' => $quantity,
                                'addon' => '',
                                'item_type' => $item_type,
                                'delete' => ($object['status'] == 'close') ? 'true' : 'false',
                                'order_id' => $this->_platform->_tgOrder['order_id'],
                                'divide_order_fee' => 0,
                                'part_mjz_discount' => 0,
                            );
                            $itemkey = $this->_get_item_key($itemtmp);
                            $order_items[$itemkey] = $itemtmp;
                        }
                    }
                }


                $objecttmp = array(
                    'obj_type' => $obj_type,
                    'obj_alias' => $object['obj_alias'] ? $object['obj_alias'] : $this->_obj_alias[$obj_type],
                    'shop_goods_id' => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                    'goods_id' => $salesMInfo['sm_id'] ? $salesMInfo['sm_id'] : 0,
                    'bn' => $object['bn'] ? $object['bn'] : null,
                    'name' => $object['name'],
                    'price' => $object['price'] ? (float)$object['price'] : bcdiv($obj_amount, $object['quantity'], 3),
                    'amount' => $obj_amount,
                    'quantity' => $object['quantity'],
                    'weight' => (float)$object['weight'],
                    'score' => (float)$object['score'],
                    'pmt_price' => (float)$object['pmt_price'],
                    'sale_price' => (float)$obj_sale_price,
                    'order_items' => $order_items,
                    'is_oversold' => ($object['is_oversold'] == true) ? 1 : 0,
                    'oid' => $object['oid'],
                    'order_id' => $this->_platform->_tgOrder['order_id'],
                    'divide_order_fee' => 0,
                    'part_mjz_discount' => 0,
                );
                unset($order_items);
                $objkey = $this->_get_obj_key($objecttmp);
                $ordersdf_object[$objkey] = $objecttmp;
            }


            // 判断ITEM有没有
            foreach ($tgOrder_object as $objkey => $object) {
                $has_old_item_del = false;
                foreach ($object['order_items'] as $itemkey => $item) {
                    // 如果已经被删除，则跳过
                    if ($item['delete'] == 'true') continue;

                    // ITEM被删除
                    if (!$ordersdf_object[$objkey]['order_items'][$itemkey]) {
                        $this->_platform->_newOrder['order_objects'][$objkey]['obj_id'] = $object['obj_id'];

                        $this->_platform->_newOrder['order_objects'][$objkey]['order_items'][$itemkey] = array('item_id' => $item['item_id'], 'delete' => 'true');

                        // 扣库存
                        if ($item['product_id']) {
                            $basicMStockLib->unfreeze($item['product_id'], $item['quantity']);

                            //[扣减]基础物料店铺冻结
                            $basicMStockFreezeLib->unfreeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], '', material_basic_material_stock_freeze::__SHARE_STORE, $item['quantity']);

                            $has_old_item_del = true;

                        }
                    }
                }
            }

            // 字段比较
            foreach ($ordersdf_object as $objkey => $object) {
                $obj_id = $tgOrder_object[$objkey]['obj_id'];
                $order_items = $object['order_items'];
                unset($object['order_items']);

                $object = array_filter($object, array($this, 'filter_null'));
                // OBJECT比较
                $diff_obj = array_udiff_assoc((array)$object, (array)$tgOrder_object[$objkey], array($this, 'comp_array_value'));

                if ($diff_obj) {
                    $diff_obj['obj_id'] = $obj_id;

                    $this->_platform->_newOrder['order_objects'][$objkey] = array_merge((array)$this->_platform->_newOrder['order_objects'][$objkey], (array)$diff_obj);

                }

                foreach ($order_items as $itemkey => $item) {
                    $item = array_filter($item, array($this, 'filter_null'));
                    // ITEM比较
                    $item_id = $tgOrder_object[$objkey]['order_items'][$itemkey]['item_id'];
                    $diff_item = array_udiff_assoc((array)$item, (array)$tgOrder_object[$objkey]['order_items'][$itemkey], array($this, 'comp_array_value'));

                    if ($diff_item) {
                        $diff_item['item_id'] = $item_id;

                        $this->_platform->_newOrder['order_objects'][$objkey]['order_items'][$itemkey] = array_merge((array)$this->_platform->_newOrder['order_objects'][$objkey]['order_items'][$itemkey], (array)$diff_item);


                        if ($diff_item['delete'] == 'false' && $item['product_id']) {

                            $basicMStockLib->freeze($item['product_id'], $item['quantity']);

                            //[增加]基础物料店铺冻结
                            $basicMStockFreezeLib->freeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], $this->_platform->_tgOrder['shop_id'], 0, material_basic_material_stock_freeze::__SHARE_STORE, $item['quantity']);

                        } elseif ($diff_item['delete'] == 'true' && $item['product_id']) {

                            $basicMStockLib->unfreeze($item['product_id'], $tgOrder_object[$objkey]['order_items'][$itemkey]['quantity']);

                            //[扣减]基础物料店铺冻结
                            $basicMStockFreezeLib->unfreeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], '', material_basic_material_stock_freeze::__SHARE_STORE, $tgOrder_object[$objkey]['order_items'][$itemkey]['quantity']);

                        } elseif (isset($diff_item['quantity']) && $item['product_id']) {
                            // 如果库存发生变化，
                            $diff_quantity = bcsub($diff_item['quantity'], $tgOrder_object[$objkey]['order_items'][$itemkey]['quantity']);

                            if ($diff_quantity > 0) {
                                $basicMStockLib->freeze($item['product_id'], abs($diff_quantity));

                                //[增加]基础物料店铺冻结
                                $basicMStockFreezeLib->freeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], $this->_platform->_tgOrder['shop_id'], 0, material_basic_material_stock_freeze::__SHARE_STORE, abs($diff_quantity));

                            } elseif ($diff_quantity < 0) {
                                $basicMStockLib->unfreeze($item['product_id'], abs($diff_quantity));

                                //[扣减]基础物料店铺冻结
                                $basicMStockFreezeLib->unfreeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], '', material_basic_material_stock_freeze::__SHARE_STORE, abs($diff_quantity));

                            }

                        }

                        $this->_platform->_newOrder['order_objects'][$objkey]['obj_id'] = $obj_id;
                    }


                }
            }

            if ($sky_ordersdf_is_fail_order) {
                $this->_platform->_newOrder['is_fail'] = 'true';
                $this->_platform->_newOrder['edit_status'] = 'true';
                $this->_platform->_newOrder['archive'] = '1';
            }
            if ($this->_platform->_newOrder['is_fail'] != 'true' && $this->_platform->_tgOrder['is_fail'] == 'true') {
                $this->_platform->_newOrder['is_fail'] = 'false';
                $this->_platform->_newOrder['edit_status'] = 'false';
                $this->_platform->_newOrder['archive'] = '0';
            }
        }
    }

    private function _get_obj_key($object)
    {
        $objkey = '';
        foreach (explode('-', $this->_platform->object_comp_key) as $field) {
            $objkey .= ($object[$field] ? trim($object[$field]) : '') . '-';
        }

        return sprintf('%u', crc32(ltrim($objkey, '-')));
    }

    private function _get_item_key($item)
    {
        $itemkey = '';
        foreach (explode('-', $this->_platform->item_comp_key) as $field) {
            if ($field == 'unit_sale_price') {
                $itemkey .= bcdiv((float)$item['sale_price'], $item['quantity'], 3) . '-';
            } else {
                $itemkey .= ($item[$field] ? $item[$field] : '') . '-';
            }
        }

        return sprintf('%u', crc32(ltrim($itemkey, '-')));
    }
}